#include <stdio.h>
#include <setjmp.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <wait.h>
//cmd = "ls -l\0"
//count = 2
//malloc(2+1) we need '\0' at  end of char *
void setargintoret(unsigned int count, char **ret, unsigned int argstart_offset, char *c, unsigned int argcount) {
    char *arg = (char *) malloc(sizeof(char) * (count + 1));
    unsigned int argoffset = 0;
    for (int i = argstart_offset; i < argstart_offset + count; i++) {
        arg[argoffset] = c[i];
        argoffset++;
    }
    arg[argoffset] = 0;
    ret[argcount - 1] = arg;
};

//cmd = "ls -l\0"
//count = 2
//ret cmd+3
char **get_args_from_cmd(char *cmd) {
    char *c = cmd;
    char **ret = malloc(0);
    unsigned int count = 0;
    unsigned int argcount = 0;
    unsigned int argstart_offset = 0;
    while (*cmd != 0) {
        if (*cmd != ' ') {
            count++;
            cmd++;
        } else {
            argcount++;

            ret = (char **) realloc(ret, argcount * (sizeof(char *)));
            setargintoret(count, ret, argstart_offset, c, argcount);
            argstart_offset = argstart_offset + count + 1;
            count = 0;
            cmd++;
        }
    }
    argcount++;

    ret = (char **) realloc(ret, argcount * (sizeof(char *)));
    setargintoret(count, ret, argstart_offset, c, argcount);
    argstart_offset = argstart_offset + count + 1;
    count = 0;
    argcount++;
    ret = (char **) realloc(ret, argcount * (sizeof(char *)));
    ret[argcount - 1] = NULL;

    return ret;
};

void docmd(char **arg) {
    execvp(arg[0], arg);
}

void freearg(char **arg) {
    char ** needfree = arg;
    while (*arg != NULL) {
        // printf("%s\n",*arg);
        free(*arg);
        arg++;
    }
    free(needfree);
}

int main(void) {
    while (1) {
        char **arg;
        fprintf(stdout, "#[MARK] ");
        char *cmd = NULL;
        size_t s = 0;
        size_t linelen = getline(&cmd, &s,stdin);
        if (!strcmp(cmd,"\n")) {
            free(cmd);
            continue;
        }
        *(cmd + linelen - 1) = '\0';
        if (linelen != -1) {
            arg = get_args_from_cmd(cmd);
        } else {
            continue;
        }

        if (!strcmp(arg[0],"cd")) {
            chdir(arg[1]);
            freearg(arg);
            free(cmd);
            // printf("%s",arg[1]);
            continue;
            // printf("%s",arg[1]);
        }
        if (!strcmp(arg[0],"exit")) {
            exit(0);
        }
        pid_t pid = fork();
        if (pid == 0) {

            docmd(arg);
            exit(1);

        } else {
            int status;
            wait(&status);
        }
        freearg(arg);
        free(cmd);
    }
}
